package org.itboys.mobile.service.mysql.mobile.order;

import org.apache.commons.lang.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.time.TimeUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.order.PearlOrderProductMapper;
import org.itboys.mobile.dao.product.SundayProductMapper;
import org.itboys.mobile.dto.count.KitchenCountDto;
import org.itboys.mobile.dto.count.KitchenCountProductDto;
import org.itboys.mobile.dto.order.KitchenOrderDto;
import org.itboys.mobile.dto.order.KitchenOrderProductDto;
import org.itboys.mobile.entity.mongo.SundayAddress;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.order.PearlOrder;
import org.itboys.mobile.entity.mysql.order.PearlOrderProduct;
import org.itboys.mobile.entity.mysql.product.SundayProduct;
import org.itboys.mobile.service.mongo.mobile.*;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mongodb.service.BaseMySqlService;
import org.itboys.param.ParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created on 2017/10/23.
 * @author 朱坤涛
 */
@Service
public class PearlOrderService extends BaseMySqlService<PearlOrder>{
    @Autowired
    private SundayMobileAddressService addressService;
    @Autowired
    private SundayMobileMemberService memberService;
    @Autowired
    private PearlOrderProductMapper orderProductMapper;
    @Autowired
    private SundayMobileCommentService commentService;
    @Autowired
    private PearlMobileCountService countService;
    @Autowired
    private SundayProductMapper productMapper;
    @Autowired
    private PearlMobileCartService cartService;
    @Autowired
    private SundayMobilePermissionService permissionService;

    //创建订单
    @Transactional
    public Map<String,Object> createOrder(Long memberId, List<Long> cartIds,Integer isUsedBalance,Long addressId,String payPassword,String remark){
        Integer isNeedToPay = 1; //是否需要支付，默认是
        Integer orderStatus = 1;
        String orderIds = "";//需要支付的订单
        String receiveName="";//收获人姓名
        String receivePhone="";//收获人电话号
        String receiveAddress="";//收获地址
        SundayAddress address = null;
        String orderNo = null;
        KitchenCountDto countDto = countService.countCart(memberId,cartIds,isUsedBalance,null);
        Map<String,Object> result = new HashMap<>();
        //准备订单数据
        PearlOrder order = new PearlOrder();
        SundayMember member = memberService.getById(memberId);
        //商城订单

            logger.info("-订单开始生成-商城订单");
            orderNo = NumberUtil.generateNumber("MALL");
            order.setFreight(countDto.getSendAmount());
            if (!LongUtil.isNotZreo(addressId)){
                throw new ErrorException("请填写收货地址。");
            }
            address = addressService.getById(addressId);
            if (StringUtils.isEmpty(address.getReceiveAddress())){
                throw new ErrorException("需要具体的门牌号");
            }
            receiveName = address.getReceiveName();
            receivePhone = address.getReceiveMobile();
            receiveAddress = address.getCityName()+address.getReceiveAddress();

            //判断是否使余额
            if (isUsedBalance==1){
                if (StringUtils.isEmpty(payPassword)){
                    throw new ErrorException("请输入支付密码");
                }
                memberService.checkPayPassWord(memberId,payPassword);
            }
            //判断是否需要支付
            if (countDto.getPayAmount().compareTo(new BigDecimal("0"))==0){
                logger.info("商城订单-"+orderNo+"不需要支付，开始创建");
                isNeedToPay = 0;
                order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DPS);
            }else {
                logger.info("商城订单-"+orderNo+"需要支付，开始创建");
                isNeedToPay = 1;
                order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);
            }
            order.setOrderNo(orderNo);
            order.setTotalAmount(countDto.getTotalAmount());
            order.setPayAmount(countDto.getPayAmount());
            order.setReceiveName(receiveName);
            order.setReceivePhone(receivePhone);
            order.setReceiveAddress(receiveAddress);
            order.setMemberId(member.getId());
            order.setRemark(remark);
            order.setBankPayAmount(countDto.getUsedBalance());
            //保存订单
            super.insert(order);
            //保存订单商品
            List<Long> productIds = new ArrayList<>();
            //本次销售的商品数量
            List<Integer> sale_nums = new ArrayList<>();
            List<PearlOrderProduct> orderProducts = new ArrayList<>();
            for (KitchenCountProductDto countProductDto:countDto.getProducts()){
                PearlOrderProduct orderProduct =
                        new PearlOrderProduct(order.getId(),countProductDto.getId(),
                                countProductDto.getPrice(),countProductDto.getName(),countProductDto.getNumber(),
                                countProductDto.getImage(),
                                countProductDto.getStandard(),countProductDto.getNum());
                orderProductMapper.insert(orderProduct);
                productIds.add(orderProduct.getProductId());
                orderProducts.add(orderProduct);

            }
            if (ListUtil.isNotNull(productIds)){
                Map<String,Object> param = new HashMap<>();
                param.put("ids",productIds);
                List<SundayProduct> products = productMapper.select(param);

                for (SundayProduct product:products){
                    for (KitchenCountProductDto countProductDto:countDto.getProducts()){
                        if (product.getId().longValue()==countProductDto.getId()){
                            product.setSaleNumber(product.getSaleNumber()+countProductDto.getNum());
                        }
                    }
                    productMapper.update(product);
                }
            }

            //删除购物车
            cartService.deleteCart(cartIds,memberId,null);
            //扣减库存
            permissionService.changeStore(productIds,sale_nums,order.getShopId());
            if (order.getUsedBalance()!=null&&order.getUsedBalance().compareTo(new BigDecimal("0"))==1){
                memberService.changeBalance(memberId,SundayCommonConstants.income_record_type_consume,orderNo,order.getUsedBalance(),null,null);
            }
            result.put("payAmount",countDto.getPayAmount());//本次付款金额
            result.put("orderIds",orderIds); //需要支付的订单
            result.put("receiveName",receiveName); //收货人
            result.put("receivePhone",receivePhone); //收货人手机号
            result.put("receiveAddress",receiveAddress); //收货地址
            result.put("isNeedToPay",isNeedToPay); //订单是否需要支付
            result.put("type",1); //1.订单2.余额充值
            result.put("info","isNeedToPay标识是否需要支付。0否，1是。type是标识支付订单类型，1是订单，2是余额充值");
            return result;
    }


    /**
     * 分页获取订单
     *
     */
    public List<KitchenOrderDto> selectOrder(HttpServletRequest request,Long memberId,List<Integer> orderStatuses){
        Map<String,Object> param = ParamUtil.packageMongoExactParam(request,"orderNo","createTime_start","createTime_end");
        param.put("memberId",memberId);
        if (ListUtil.isNotNull(orderStatuses)){
            if (orderStatuses.get(0)!=0){
                param.put("orderStatuses",orderStatuses);
            }
        }
        return pakageDtoMuilt(super.select(param));
    }

    /**
     * 查询订单详情
     */
    public KitchenOrderDto findOne(Long orderId,Long memberId){
        return pakageDtoSingle(super.find(orderId),null);
    }

    /**
     * 取消订单
     */
    public void cancelOrder(Long orderId,Long memberId){
        PearlOrder order = super.find(orderId);
        String msg = null;
        if (order.getOrderStatus()!=SundayCommonConstants.ORDER_STATUS_DFK){
            msg = "非待付款订单，不能取消";
        }else if (order.getOrderStatus()!=SundayCommonConstants.ORDER_STATUS_DPS){
            msg = "非待配送订单，不能取消";
        }
        if (StringUtils.isNotEmpty(msg)){
            throw new ErrorException(msg);
        }
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YQX);
        if (order.getUsedBalance()!=null&&order.getUsedBalance().compareTo(new BigDecimal("0"))==1){
            memberService.changeBalance(order.getMemberId(),SundayCommonConstants.income_record_type_cancel,order.getOrderNo(),order.getUsedBalance(),null,null);
        }
        super.update(order);
    }

    /**
     * 确认收货
     */
    @Transactional
    public void confirmReceive(Long orderId,Long memberId){
        PearlOrder order = checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_PSZ,"非配送中订单，不能确认收货",memberId);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YSH);
        order.setReceiveTime(new Date());
        BigDecimal thisAmount = order.getPayAmount();
        if (order.getUsedBalance()!=null){
            thisAmount.add(order.getUsedBalance());
        }
        super.update(order);
    }

    /**
     * 商城订单发货
     */
    @Transactional
    public void sendOrder(Long orderId,Long memberId){
        PearlOrder order = checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_DPS,"非待配送订单，不能发货",null);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_PSZ);
        order.setSendTime(new Date());
        super.update(order);
    }

    /**
     * 评论订单
     * @param scores 评分
     * 图片集合，固定大小=productIds集合大小*3。。每个商品限制最大传入三张，没有图片的使用noImage字符传固定值。
     */
    public void commentOrder(Long orderId,List<Long> productIds,List<String> contents,List<Integer> scores,List<String> images,Long memberId){
        String msg ="";
        if(ListUtil.isNull(productIds)||ListUtil.isNull(contents)||ListUtil.isNull(scores)){
            msg="评论接口参数有错误(为空)";
        }
        if(productIds.size()!=contents.size()||productIds.size()!=scores.size()||contents.size()!=scores.size()){
            msg="评论接口参数有错误（参数不对应）";
        }
        if(productIds.size()*3!=images.size()){
            msg="评论接口参数有错误（图片参数）";
        }
        if(msg!=""){
            throw new ErrorException(msg);
        }
        PearlOrder order = checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_YSH,"非待评论订单，不能评论",memberId);
        SundayMember member = memberService.getById(memberId);
        commentService.generateComment(productIds,contents,scores,images,memberId,member.getImage(),member.getNickName(),SundayProduct.class.getSimpleName());
        //更改订单状态
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YPJ);
        super.update(order);
    }

    /**
     * 校验订单信息
     */
    public PearlOrder checkOrder(Long orderId,Integer status,String msg,Long memberId){
        PearlOrder order = super.find(orderId);
        if (status!=null&&order.getOrderStatus()!=status){
            throw new ErrorException(msg);
        }
        if (LongUtil.isNotZreo(memberId)&&order.getMemberId().longValue()!=memberId){
            throw new ErrorException("数据错误，请重试");
        }
        return order;
    }
    /**
     * 获取各订单状态的数量
     * @param memberId
     * @return
     */
    public Map<String,Object> getOrderNumber(Long memberId){
        Map<String,Object> result = new HashMap<>();
        Integer dfk=0;
        Integer dps=0;
        Integer psz=0;
        Integer dpj=0;
        String msg="dfk(待付款)，dps(待配送)，psz(配送中)，dpj(待评价)";
        Map<String,Object> param = new HashMap<String,Object>();
        List<Integer> orderStatuses = new ArrayList<Integer>();
        //SundayMember member = memberService.getById(memberId);
        param.put("memberId",memberId);
        orderStatuses.add(SundayCommonConstants.ORDER_STATUS_DFK);
        orderStatuses.add(SundayCommonConstants.ORDER_STATUS_DPS);
        orderStatuses.add(SundayCommonConstants.ORDER_STATUS_PSZ);
        orderStatuses.add(SundayCommonConstants.ORDER_STATUS_YSH);
        List<PearlOrder> orders = super.select(param);
        for(PearlOrder order:orders){
            if(order.getOrderStatus()==SundayCommonConstants.ORDER_STATUS_DFK){
                dfk++;
            }else if(order.getOrderStatus()==SundayCommonConstants.ORDER_STATUS_DPS){
                dps++;
            }else if(order.getOrderStatus()==SundayCommonConstants.ORDER_STATUS_PSZ){
                psz++;
            }else if(order.getOrderStatus()==SundayCommonConstants.ORDER_STATUS_YSH){
                dpj++;
            }
        }
        result.put("dfk",dfk);
        result.put("dps",dps);
        result.put("psz",psz);
        result.put("dpj",dpj);
        result.put("msg",msg);

        return result;
    }

    /**
     * 组装DTO
     * @param order
     * @return
     */
    public KitchenOrderDto pakageDtoSingle(PearlOrder order, List<KitchenOrderProductDto> products){
        if (ListUtil.isNull(products)){
            Map<String,Object> param = new HashMap<>();
            param.put("orderId",order.getId());
            products = new ArrayList<KitchenOrderProductDto>();
            for (PearlOrderProduct orderProduct:orderProductMapper.select(param)){
                if (orderProduct.getOrderId().longValue()==order.getId()){
                    products.add(new KitchenOrderProductDto(orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(),orderProduct.getName(),orderProduct.getNumber(),orderProduct.getImage(),
                    orderProduct.getStandard(),orderProduct.getNum()));
                }
            }
        }
        String payTime= order.getPayTime()!=null? TimeUtils.format(order.getPayTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String sendTime= order.getSendTime()!=null?TimeUtils.format(order.getSendTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String receiveTime= order.getReceiveTime()!=null?TimeUtils.format(order.getReceiveTime(),"yyyy-MM-dd HH:mm:ss"):null;

        return new KitchenOrderDto(order.getId(),order.getCreateTime(),order.getCreateDate(),
                order.getOrderNo(),order.getTotalAmount(), order.getPayAmount(),
                order.getExpressNo(), order.getOrderStatus(), order.getReceiveName(),order.getReceivePhone(), order.getReceiveAddress(),
                order.getFreight(),order.getRemark(), order.getShopId(), order.getShopName(),
                payTime,sendTime, receiveTime,  products);
    }

    public List<KitchenOrderDto> pakageDtoMuilt(List<PearlOrder> orders){
        List<KitchenOrderDto> dtos= new ArrayList<KitchenOrderDto>();
        List<Long> orderIds = new ArrayList<>();
        for(PearlOrder order:orders){
            orderIds.add(order.getId());
        }
        Map<String,Object> param =new HashMap<String ,Object>();
        param.put("orderIds",orderIds);
        List<PearlOrderProduct> orderProducts = orderProductMapper.select(param);
        for(PearlOrder order:orders){
            List<KitchenOrderProductDto> ps = new ArrayList<KitchenOrderProductDto>();
            for(PearlOrderProduct orderProduct:orderProducts){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    ps.add(new KitchenOrderProductDto(orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum()));
                }
            }
            dtos.add(pakageDtoSingle(order,ps));
        }
        return dtos;
    }
}
